#include "AsynchConnector.h"
#include "BasePacket.h"
#include "netstream.h"
volatile long CAsynchConnector::_ref = 0;
CAsynchConnector::CAsynchConnector()
{
	InterlockedIncrement( &_ref );
}

CAsynchConnector::~CAsynchConnector(void)
{
	this->cancel();
	InterlockedDecrement( &_ref );
}

void CAsynchConnector::handle_connect(const ACE_Asynch_Connect::Result &result)
{
	int ret = -1;
	if ( result.error() != 0 )
	{
		IMessageQueue* pMessageQueue = (IMessageQueue*)result.act();
		if( pMessageQueue )
		try
		{
			CNetworkPacket* pPacket = new CNetworkPacket( 2, NULL, -1 );
			CNetInStream in( const_cast< char* >( pPacket->data() ), pPacket->size() );
			in
				.write( _byte(SYSTEM_MESSAGE_TYPE) )
				.write( _byte(EVENT_ERROR) )
				.end();

			pMessageQueue->PushMessage( pPacket );
		}
		catch( CNetworkPacket* pPacket )
		{
			pPacket->release();
		}

	}

	__super::handle_connect(result);
	delete this;
}

int CAsynchConnector::validate_connection (const ACE_Asynch_Connect::Result& result,
								 const ACE_INET_Addr &remote,
								 const ACE_INET_Addr& local)
{
	if( result.error() != 0 )
		return -1;

	//ACE_SOCK_SEQPACK_Association ass(handle());
	//ass.get_remote_addr(m_RemoteAddress);
	int opt = 1;
	// Set Keepalive option;
	if( setsockopt((SOCKET)result.connect_handle(), SOL_SOCKET, SO_KEEPALIVE, (char*)&opt, sizeof(opt)) != SOCKET_ERROR )
	{
		/* Argument structure for SIO_KEEPALIVE_VALS */
		struct tcp_keepalive 
		{
			u_long  onoff;
			u_long  keepalivetime;
			u_long  keepaliveinterval;
		};

		tcp_keepalive inkeepalive = { 1, 5000, 5000 };
		tcp_keepalive outkeepalive;
		DWORD dwRet = 0;
		WSAIoctl( (SOCKET)result.connect_handle(), (IOC_IN|IOC_VENDOR|4), (LPVOID)&inkeepalive, sizeof(inkeepalive), (LPVOID)&outkeepalive, sizeof(outkeepalive), &dwRet, NULL, NULL );
	}

	return 0;
}